package com.ustc.hewei.seckillmodule.serviceImpl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ustc.hewei.commonmodule.dto.Result;
import com.ustc.hewei.commonmodule.dto.UserDTO;
import com.ustc.hewei.commonmodule.entity.VoucherOrder;
import com.ustc.hewei.commonmodule.mapper.VoucherOrderMapper;
import com.ustc.hewei.commonmodule.service.ISeckillVoucherService;
import com.ustc.hewei.commonmodule.service.IVoucherOrderService;
import com.ustc.hewei.commonmodule.utils.SegmentID;
import com.ustc.hewei.commonmodule.utils.Snowflake;
import com.ustc.hewei.nettyrpc2_0.common.annotation.AutowireService;
import com.ustc.hewei.nettyrpc2_0.common.annotation.RPCService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hewei
 * @since 2022-10-05
 */
@Service
@RPCService(value = IVoucherOrderService.class)
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {

    private static final Logger logger = LoggerFactory.getLogger(VoucherOrderServiceImpl.class);
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private SegmentID segmentID;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private ISeckillVoucherService seckillVoucherService;
    private static final DefaultRedisScript<Long> SECKILL_SCRIPT;

    static {
        SECKILL_SCRIPT = new DefaultRedisScript<>();
        SECKILL_SCRIPT.setResultType(Long.class);
        SECKILL_SCRIPT.setLocation(new ClassPathResource("secKillVoucher.lua"));
    }

    public SegmentID getSegmentID() {
        return segmentID;
    }

    public void setSegmentID(SegmentID segmentID) {
        this.segmentID = segmentID;
    }

    @Override
    public Result secKillVoucher(UserDTO userDTO, Long voucherId) {
        if (userDTO == null) {
            Result.fail("请先登录!");
        }
        Long userID = userDTO.getId();
        Long execute = stringRedisTemplate.execute(SECKILL_SCRIPT, Collections.emptyList(), voucherId.toString(), userID.toString());
        int res = execute.intValue();
        if (res == 1) {
            return Result.fail("库存不足!");
        }
        if (res == 2) {
            logger.error("用户 {}, 重复下单", userID);
            return Result.fail("请勿重复下单!");
        }
        VoucherOrder order = new VoucherOrder();
        Long orderId = segmentID.getId("sellVoucher");
        order.setId(orderId).setUserId(userID).setVoucherId(voucherId);
        rabbitTemplate.convertAndSend("voucherOrder", order);
        return Result.ok(orderId);
    }

    @Transactional(rollbackFor = Exception.class)
    public void creatOrder(VoucherOrder order) {
        Long voucherId = order.getVoucherId();
        seckillVoucherService.update().eq("voucher_id", voucherId).setSql("stock = stock - 1").update();
        save(order);
    }
}
